package com.hundsun.cprs.yyt.web.action.quota;

import com.alibaba.excel.exception.ExcelGenerateException;
import com.alibaba.fastjson.JSON;
import com.hundsun.cprs.yyt.service.common.Constants;
import com.hundsun.cprs.yyt.service.quota.domain.QuotaImportLog;
import com.hundsun.cprs.yyt.service.quota.domain.query.QuotaImportLogQuery;
import com.hundsun.cprs.yyt.service.quota.service.QuotaImportLogService;
import com.hundsun.cprs.yyt.util.DateUtil;
import com.hundsun.cprs.yyt.util.excel.EasyExcelUtil;
import com.hundsun.cprs.yyt.web.vo.excel.QuotaImportExcelVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.data.redis.core.BoundValueOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.hundsun.cprs.yyt.common.enums.EnumBusinessCode;
import com.hundsun.cprs.yyt.common.exception.ServiceCodeException;
import com.hundsun.cprs.yyt.service.account.enums.EnumQuotaTransType;
import com.hundsun.cprs.yyt.service.quota.domain.Quota;
import com.hundsun.cprs.yyt.service.quota.domain.query.QuotaExchangeRecordQuery;
import com.hundsun.cprs.yyt.service.quota.domain.query.QuotaHoldQuery;
import com.hundsun.cprs.yyt.service.quota.domain.query.QuotaQuery;
import com.hundsun.cprs.yyt.service.quota.dto.QuotaHoldEditInfo;
import com.hundsun.cprs.yyt.service.quota.dto.QuotaHoldInfo;
import com.hundsun.cprs.yyt.service.quota.enums.EnumQuotaExchangeStatus;
import com.hundsun.cprs.yyt.service.quota.enums.EnumQuotaType;
import com.hundsun.cprs.yyt.service.quota.service.QuotaExchangeRecordService;
import com.hundsun.cprs.yyt.service.quota.service.QuotaHoldService;
import com.hundsun.cprs.yyt.service.quota.service.QuotaService;
import com.hundsun.cprs.yyt.util.BeanUtils;
import com.hundsun.cprs.yyt.web.action.BaseAction;
import com.hundsun.cprs.yyt.web.vo.JsonModel;
import org.springframework.web.multipart.MultipartFile;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * 配额相关视图控制类
 * @author herong22384
 * @date 2019/8/7 14:41
 */
@Controller
@RequestMapping("quota/")
public class QuotaAction extends BaseAction {

    public static final String YYT_BATCH_IMPORT_LOCK = Constants.YYT_BATCH_IMPORT_LOCK;

    @Autowired
    private QuotaService quotaService;
    @Autowired
    private QuotaHoldService quotaHoldService;
    @Autowired
    private QuotaExchangeRecordService recordService;
    @Autowired
    private QuotaImportLogService logService;
    @Autowired
    private RedisTemplate redisTemplate;

    @RequestMapping("type/list")
    public void queryTypeList(@ModelAttribute("query")QuotaQuery query, ModelMap model){
        quotaService.queryByPage(query);
        model.addAttribute("quotaList", quotaService.queryAll());
        model.addAttribute("enumQuoteType",EnumQuotaType.toMap());
    }

    @RequestMapping("hold/list")
    public void queryHoldList(@ModelAttribute("query")QuotaHoldQuery query, ModelMap model){
        quotaHoldService.queryByPage(query);
        model.addAttribute("quotaList", quotaService.queryAll());
        
        QuotaHoldQuery sumQuery = new QuotaHoldQuery();
        BeanUtils.copyProperties(query, sumQuery);
        model.put("remainingQuota", quotaHoldService.sumRemainingQuotaByQuery(sumQuery));
    }

    @RequestMapping("exchange/list")
    public void queryExchangeList(@ModelAttribute("query")QuotaExchangeRecordQuery query, ModelMap model){
        recordService.queryByPage(query);
        model.addAttribute("quotaList", quotaService.queryAll());
        model.addAttribute("enumQuoteType",EnumQuotaType.toMap());
        model.addAttribute("enumQuoteExchangeStatus",EnumQuotaExchangeStatus.toMap());
    }

    @RequestMapping(value = "type/add",method = RequestMethod.GET)
    public void addType(){}

    @RequestMapping(value = "type/add",method = RequestMethod.POST)
    @ResponseBody
    public JsonModel addType(@RequestBody Quota quota){
        try{
            quotaService.createQuote(quota);
            return new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"新增成功");
        }catch (Exception e){
            log.error(e);
            return new JsonModel(JsonModel.RESULD_CODE_FAIL,"新增配额类型失败:" + e.getMessage());
        }
    }

    @RequestMapping(value = "type/edit",method = RequestMethod.GET)
    public void editType(@RequestParam("quotaId")Long quotaId,ModelMap model){
        model.addAttribute("data",quotaService.selectQuoteById(quotaId));
    }

    @RequestMapping(value = "type/edit",method = RequestMethod.POST)
    @ResponseBody
    public JsonModel editType(@RequestBody Quota quota){
        try{
            quotaService.modifyQuote(quota);
            return new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"修改成功");
        }catch (Exception e){
            log.error(e);
            return new JsonModel(JsonModel.RESULD_CODE_FAIL,"修改配额类型失败:" + e.getMessage());
        }
    }

    @RequestMapping(value = "type/delete",method = RequestMethod.POST)
    @ResponseBody
    public JsonModel deleteType(@RequestParam("quotaId")Long quotaId){
        try{
            quotaService.deleteQuote(quotaId);
            return new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"删除成功");
        }catch (Exception e){
            log.error(e);
            return new JsonModel(JsonModel.RESULD_CODE_FAIL,"删除失败:" + e.getMessage());
        }
    }

    @RequestMapping(value = "hold/edit",method = RequestMethod.GET)
    public void editHold(@RequestParam("userId")Long userId,@RequestParam("quotaId")Long quotaId,ModelMap model){
        model.addAttribute("data",quotaHoldService.getQuoteHoldByUserAndQuoteId(userId,quotaId));
        model.addAttribute("enumQuotaType",EnumQuotaType.toMap());
    }

    //账户配额调整
    @RequestMapping(value = "hold/edit",method = RequestMethod.POST)
    @ResponseBody
    public JsonModel editHold(@RequestBody QuotaHoldEditInfo quotaHoldEditInfo){
        try{
            //先获取配额持仓详情
            QuotaHoldInfo quotaHoldInfo = quotaHoldService.getQuoteHoldByUserAndQuoteId(quotaHoldEditInfo.getUserId(),quotaHoldEditInfo.getQuotaId());
            if (quotaHoldInfo == null){
                throw new ServiceCodeException(EnumBusinessCode.BUSINESS_3231.getErrorNo(),EnumBusinessCode.BUSINESS_3231.getErrorInfo());
            }
            if (quotaHoldEditInfo.getOperatorType().equals("0")){
                //增加配额
                quotaHoldService.addQuota(quotaHoldInfo.getUserId(),quotaHoldInfo.getQuotaId(),quotaHoldEditInfo.getAmount(),EnumQuotaTransType.TRANS_0202.getCode(),"手工划入配额");
            }else {
                //减少配额
                quotaHoldService.deductQuota(quotaHoldInfo.getUserId(),quotaHoldInfo.getQuotaId(),quotaHoldEditInfo.getAmount(),EnumQuotaTransType.TRANS_0102.getCode(),"手工划出配额");
            }
            return new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"配额调整成功");
        }catch (Exception e){
            log.error(e);
            return new JsonModel(JsonModel.RESULD_CODE_FAIL,"配额调整失败:" + e.getMessage());
        }
    }

    @RequestMapping(value = "exchange/unfreeze",method = RequestMethod.GET)
    public void unfreezeByHand(@RequestParam("recordId")Long recordId,ModelMap model){
        model.addAttribute("data",recordService.selectByRecordId(recordId));
        model.addAttribute("enumQuotaType",EnumQuotaType.toMap());
    }

    //手工解冻
    @RequestMapping(value = "exchange/unfreeze",method = RequestMethod.POST)
    @ResponseBody
    public JsonModel unfreezeByHand(@RequestBody QuotaHoldEditInfo quotaHoldEditInfo){
        try{
            recordService.unfreezeByHand(quotaHoldEditInfo.getRecordId(),quotaHoldEditInfo.getAmount());
            return new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"手工解冻成功");
        }catch (Exception e){
            log.error(e);
            return new JsonModel(JsonModel.RESULD_CODE_FAIL,"手工解冻失败:" + e.getMessage());
        }
    }

    //配额批量导入
    @RequestMapping(value = "hold/import")
    public String holdImport(@ModelAttribute("query")QuotaImportLogQuery query){
        if (query.getStartDate()==null){
            query.setStartDate(DateUtil.getBeginOfDay(new Date()));
        }
        if (query.getEndDate() == null){
            query.setEndDate(DateUtil.getEndOfDay(new Date()));
        }
        query.setOrderRule("DESC");
        logService.queryByPage(query);
        return "quota/hold/batchImportQuota";
    }

    @RequestMapping(value = "batch/import",method=RequestMethod.POST)
    public @ResponseBody
    String holdImport(@RequestParam("file") MultipartFile file){
        try{
            if (redisTemplate.hasKey(YYT_BATCH_IMPORT_LOCK)){
                JsonModel result = new JsonModel(JsonModel.RESULD_CODE_FAIL,"上次导入系统还未处理完成，请稍后再试");
                return JSON.toJSONString(result);
            }

            //设置全局锁，在本次导入操作完成时释放
            BoundValueOperations valueOperations = redisTemplate.boundValueOps(YYT_BATCH_IMPORT_LOCK);
            valueOperations.set(YYT_BATCH_IMPORT_LOCK,2L,TimeUnit.HOURS);

            List<QuotaImportExcelVo> uploadDatas = EasyExcelUtil.readExcel(file, QuotaImportExcelVo.class);
            List<QuotaImportLog> datas = new ArrayList<>();
            if(uploadDatas.size()>0){
                for(QuotaImportExcelVo temp : uploadDatas) {
                    QuotaImportLog log = new QuotaImportLog();
                    log.setFundAccount(temp.getFundAccount());
                    log.setQuotaName(temp.getQuotaName());
                    log.setQuotaAmount(temp.getQuotaAmount());
                    log.setStatus(0);
                    datas.add(log);
                }

                //生成批量导入流水记录
                logService.batchInsert(datas);
            }
            //处理配额导入业务
            logService.handleBatchImport();

            Map<String,Object> importStatInfo = new HashMap<String,Object>();
            importStatInfo.put("total", uploadDatas.size());
            importStatInfo.put("uniqueTotal", datas.size());

            JsonModel result = new JsonModel(JsonModel.RESULD_CODE_SUCCESS,"success",importStatInfo);
            return JSON.toJSONString(result);
        }catch (Exception e){
            log.error(e);
            redisTemplate.delete(YYT_BATCH_IMPORT_LOCK);
            JsonModel result = new JsonModel(JsonModel.RESULD_CODE_FAIL,"导入失败:数据解析异常，请检查表格数据是否按要求填写");
            return JSON.toJSONString(result);
        }
    }

    @Override
    protected void initBinder(WebDataBinder binder) {
        // 注册默认的日期格式化类型: yyyy-MM-dd
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateFormat.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }
}
